import com.sun.org.apache.xerces.internal.impl.xs.SchemaNamespaceSupport;
/*
	                   _ooOoo_
	                  o8888888o
	                  88" . "88
	                  (| -_- |)
	                  O\  =  /O
	               ____/`---'\____
	             .'  \\|     |//  `.
	            /  \\|||  :  |||//  \
	           /  _||||| -:- |||||-  \
	           |   | \\\  -  /// |   |
	           | \_|  ''\-/''  |   |
	           \  .-\__  `-`  ___/-. /
	         ___`. .'  /-.-\  `. . __
	      ."" '<  `.___\_<|>_/___.'  >'"".
	     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
	     \  \ `-.   \_ __\ /__ _/   .-` /  /
	======`-.____`-.___\_____/___.-`____.-'======
	                   `=-='
 */
import domain.BlockManager;
import domain.Directory;
import domain.File;
import domain.User;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;

//总管理
public class FileManager {
    //模拟实现简陋的多用户
    private Map<String, User> users;
    //当前是哪个文件在使用系统
    private User currentUser;
    private BlockManager blockManager;
    private Scanner scanner;

    public FileManager() {
        users = new HashMap<>();
        blockManager = new BlockManager();
        scanner = new Scanner(System.in);
        createUsers();
    }

    //创建一些用户和密码
    private void createUsers() {
        //模拟多个用户
        users.put("李欣桐", new User("李欣桐", "1234"));
        users.put("司马懿", new User("司马懿", "666"));
    }

    //注册
    public void register(String username, String password) {
        User user = new User(username, password);
        users.put(username, user);
    }

    //给该用户初始化用户目录
    public void allocateDirectory(User user) {
        user.setUserDirectory(new Directory(user.getUsername()));
        //先将当前的用户目录标记为当前使用的目录
        user.setCurrentDirectory(user.getUserDirectory());
    }

    //登录
    public void login() {
        //输入用户名和密码
        System.out.print("Username： ");
        String username = scanner.nextLine();
        System.out.print("password： ");
        String password = scanner.nextLine();
        //如果已经有这个用户，直接从表中取出，赋值给user
        User user = users.get(username);
        //如果在用户表中有该用户，则直接取出来，同时密码也要匹配成功
        if (user != null && user.getPassword().equals(password)) {
            //赋值当前用户，表示是某某使用系统
            currentUser = user;
            //给该用户初始化用户目录
            allocateDirectory(user);
            System.out.println("登录成功！");
        } else {
            //注册
            System.out.println("抱歉没有这个用户，请注册一个");
            System.out.print("输入要注册的用户名： ");
            String Rusername = scanner.nextLine();
            String Rpassword;
            String Apassword;
            //确认密码
            while (true) {
                System.out.print("输入要注册的密码： ");
                Rpassword = scanner.nextLine();
                System.out.print("请再次输入密码，确认密码： ");
                Apassword = scanner.nextLine();
                if (Rpassword.equals(Apassword)) {
                    register(Rusername, Rpassword);
                    System.out.println("注册成功，重新登录");
                    login();
                    break;
                } else {
                    System.out.println("两次密码不一致，请重新注册！");
                }
            }
        }
    }

    //展示所有文件和文件夹
    public void dir() {
        //没有用户，提醒用户重新登录
        if (currentUser == null) {
            System.out.println("当前用户为空，请进行登录");
            return;
        }
        Directory currentDirectory = currentUser.getCurrentDirectory();
        if (currentDirectory == null) {
            System.out.println("没有当前目录");
            return;
        }
        //如果上方的两个if都没进入，则使用foreach进行打印文件
        System.out.println("文件：");
        int num1 = 1;
        for (Map.Entry<String, File> file : currentDirectory.getAllFile().entrySet()) {
            System.out.println(num1 + ". 文件名：" + file.getValue().getName() + " 文件大小："
                    + file.getValue().getFileLength() + " 文件的权限等级："
                    + file.getValue().getSave() + " 文件存储的物理地址块："
                    + file.getValue().getSave());
            num1++;
        }
        num1 = 1;
        //打印文件夹
        System.out.println("文件夹：");
        for (Map.Entry<String, Directory> directoryEntry : currentDirectory.getAllDirectory().entrySet()) {
            System.out.println(num1 + ". 文件夹名：" + directoryEntry.getValue().getName());
            num1++;
        }
    }

    //创建文件
    public void create(String fileName) throws Exception {
        //没有用户，提醒用户重新登录
        if (currentUser == null) {
            System.out.println("当前用户为空，请进行登录");
            return;
        }
        Directory currentDirectory = currentUser.getCurrentDirectory();
        if (currentDirectory == null) {
            System.out.println("没有文件夹");
            return;
        }
        if (currentDirectory.getFile(fileName) != null) {
            System.out.println("文件已经存在: " + fileName);
            return;
        }
        //分配物理块
        int blockId = blockManager.allocateBlocksId();
        //如果磁盘块 == -1 证明已经没有空间了
        //直接报错，暴力手段！！！
        if (blockId == -1) {
            throw new Exception("磁盘已无空间！兄弟，别乱来了");
        }
        //开始创建文件
        System.out.print("请输入文件的保护码，1(读写)或0(只读)：");
        String _save = scanner.nextLine();
        int save = Integer.parseInt(_save);
        System.out.print("请输入文件的大小（自定义）：");
        String _size = scanner.nextLine();
        int size = Integer.parseInt(_size);
        //判断是否有足够的空间存储文件大小
        if (sizelegal(blockManager, blockId, size)) {
//            blockId = blockManager.fillBlock(size + blockId, blockId);
            File file = new File(fileName, blockId, size, save);
            currentDirectory.addFile(file);
            System.out.println("文件创建成功，文件名：" + fileName);
        } else {
            System.out.println("磁盘空间不足，请重新创建文件，指定正确的文件大小");
        }
    }

    //判断是否有足够的空间存储文件大小（顺序分配）
    //size：文件要求的大小
    public boolean sizelegal(BlockManager blockManager, int blockId, int size) {
        int count = 0;
        boolean[] flag = blockManager.getBlocksIsUse();
        for (int i = blockId; i < flag.length; i++) {
            if (!flag[i])
                count++;
        }
        return count >= size;
    }

    //删除文件
    public void delete(String fileName) {
        //没有用户，提醒用户重新登录
        if (currentUser == null) {
            System.out.println("当前用户为空，请进行登录");
            return;
        }
        Directory currentDirectory = currentUser.getCurrentDirectory();
        if (currentDirectory == null) {
            System.out.println("没有文件夹");
            return;
        }
        File file = currentDirectory.getFile(fileName);
        if (file == null) {
            System.out.println("文件没有找到：" + fileName);
            return;
        }
        //把内存块回收
        blockManager.freeBlock(file.getBlockId());
        currentDirectory.deleteFile(file);
        System.out.println("文件已删除：" + fileName);
    }

    //打开文件
    public void open(String fileName) {
        //没有用户，提醒用户重新登录
        if (currentUser == null) {
            System.out.println("当前用户为空，请进行登录");
            return;
        }
        Directory currentDirectory = currentUser.getCurrentDirectory();
        if (currentDirectory == null) {
            System.out.println("没有文件夹");
            return;
        }
        File file = currentDirectory.getFile(fileName);
        //没有该文件
        if (file == null) {
            System.out.println("文件没有找到: " + fileName);
            return;
        }
        currentUser.setCurrentFile(file);//把打开的文件，标记为当前打开文件
        System.out.println("打开文件：" + fileName);
    }

    //关闭文件
    public void close() {
        //没有用户，提醒用户重新登录
        if (currentUser == null) {
            System.out.println("当前用户为空，请进行登录");
            return;
        }
        File currentFile = currentUser.getCurrentFile();
        if (currentFile == null) {
            System.out.println("没有文件被打开");
            return;
        }
        currentUser.setCurrentFile(null);
        System.out.println("被关闭的文件是: " + currentFile.getName());
    }

    //读文件
    public void read() {
        //没有用户，提醒用户重新登录
        if (currentUser == null) {
            System.out.println("当前用户为空，请进行登录");
            return;
        }
        //由于前面的open指令已经将currentUser的currentFile修改
        File currentFile = currentUser.getCurrentFile();
        if (currentFile == null) {
            System.out.println("没有文件被打开");
            return;
        }
        String content = blockManager.readBlock(currentFile.getBlockId());
        //用随机值+磁盘块号的方法，表示文件里面的内容
        System.out.println("文件的内容是：" + content + "，美好且魔幻的世界，继续享受人生，感受世间冷暖吧！");
    }

    //写文件
    public void write(String content) {
        //没有用户，提醒用户重新登录
        if (currentUser == null) {
            System.out.println("当前用户为空，请进行登录");
            return;
        }
        File currentFile = currentUser.getCurrentFile();
        if (currentFile == null) {
            System.out.println("没有文件被打开");
            return;
        }
        if (currentFile.getSave() == 0) {
            System.out.println("文件只是只读，不允许修改，非法操作，我要报警啦！");
            return;
        }
        blockManager.writeBlock(currentFile.getBlockId(), content);
        System.out.println("文件内容已更新");
    }

    //创建文件夹
    public void mkdir(String directoryName) {
        //没有用户，提醒用户重新登录
        if (currentUser == null) {
            System.out.println("当前用户为空，请进行登录");
            return;
        }
        Directory currentDirectory = currentUser.getCurrentDirectory();
        if (currentDirectory == null) {
            System.out.println("当前没有文件夹");
            return;
        }
        if (currentDirectory.getDirectory(directoryName) != null) {
            System.out.println("文件夹已存在: " + directoryName);
            return;
        }
        Directory directory = new Directory(directoryName);
        currentDirectory.addDirectory(directory);
        System.out.println("文件夹已创建：" + directoryName);
    }

    public void remove(String directoryName) {
        //没有用户，提醒用户重新登录
        if (currentUser == null) {
            System.out.println("当前用户为空，请进行登录");
            return;
        }
        Directory currentDirectory = currentUser.getCurrentDirectory();
        if (currentDirectory == null) {
            System.out.println("没有文件或者文件夹");
            return;
        }
        Directory directory = currentDirectory.getDirectory(directoryName);
        if (directory == null) {
            System.out.println("文件夹没有被找到: " + directoryName);
            return;
        }
        currentDirectory.deleteDirectory(directory);
        System.out.println("文件夹已移除：" + directoryName);
    }

    //展示
    public void memu(){
        System.out.println("login ---- 登录");
        System.out.println("create ---- 创建文件");
        System.out.println("delete ---- 删除文件");
        System.out.println("dir ---- 展示所有文件和文件夹");
        System.out.println("mkdir ---- 创建文件夹");
        System.out.println("remove ---- 删除文件夹");
        System.out.println("open ---- 打开文件");
        System.out.println("close ---- 关闭文件");
        System.out.println("read ---- 读文件");
        System.out.println("write ---- 写文件");
    }

    //运行
    public void run() throws Exception {
        while (true) {
            System.out.print("> ");
            //读入命令
            String command = scanner.nextLine();
            if (command.startsWith("login")) {
                login();
            } else if (command.startsWith("create")) {
                //substring是为了保证输出形式：create[一个空格]文件名
                String fileName = command.substring(7);
                create(fileName);
            } else if (command.startsWith("dir")) {
                dir();
            } else if (command.startsWith("delete")) {
                String fileName = command.substring(7);
                delete(fileName);
            } else if (command.startsWith("open")) {
                String fileName = command.substring(5);
                open(fileName);
            } else if (command.startsWith("write")) {
                String content = command.substring(6);
                write(content);
            } else if (command.startsWith("read")) {
                read();
            } else if (command.startsWith("mkdir")) {
                String directoryName = command.substring(6);
                mkdir(directoryName);
            } else if (command.startsWith("remove")) {
                String directoryName = command.substring(7);
                remove(directoryName);
            } else if (command.startsWith("close")) {
                close();
            }else if(command.startsWith("?")){
                memu();
            }
        }
    }
}
